package jmail;

import java.io.*;
import java.util.Enumeration;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.mail.*;
import javax.mail.internet.MimeUtility;
import javax.mail.search.OrTerm;
import javax.mail.search.SearchTerm;
import jmail.file.Endir;
import jmail.file.Students;
import jmail.file.XmlData;
import jmail.window.JMainFrame.MessageCallBack;

public class ReceiveEmail implements Runnable {

    private boolean timeToQuit = false;
    private String pop3server, protocol, username, password, port, foldername;
    private MessageCallBack mc;
    private TreeMap map = new TreeMap();
    private TreeMap tm;
    private String stunum;
    private String assignname;

    public ReceiveEmail(String pop3server, String protocol, String username, String password, String port, String foldername, MessageCallBack mc) {
        this.pop3server = pop3server;
        this.protocol = protocol;
        this.username = username;
        this.password = password;
        this.port = port;
        this.foldername = foldername;
        this.mc = mc;
    }

    public void processMultipart(Multipart mp)
            throws MessagingException {

        for (int i = 0; i < mp.getCount(); i++) {
            processPart(mp.getBodyPart(i));
        }

    }

    public void processPart(Part p) {
        try {
            String fileName = p.getFileName();
            String disposition = p.getDisposition();
            String contentType = p.getContentType();
            if (contentType.toLowerCase().startsWith("multipart/")) {
                processMultipart((Multipart) p.getContent());
            } else if (fileName == null
                    && (Part.ATTACHMENT.equalsIgnoreCase(disposition)
                    || !contentType.equalsIgnoreCase("text/plain"))) {
                // pick a random file name. This requires Java 1.2 or later.
                String filepath = Config.getProps("jmail.dir") + "\\" + stunum + "\\" + assignname + "\\邮件正文.html";
                Endir endir = new Endir(filepath);
                //fileName = File.createTempFile("邮件正文", ".txt").getName();
                fileName = endir.createTempFile().getName();
                tm.put(fileName, fileName);
            }
            if (fileName == null) { // likely inline
                //p.writeTo(System.out);
            } else {
                //String s = fileName.substring(8, fileName.indexOf("?="));
                //文件名经过了base64编码,下面是解码  
                //fileName = base64Decoder(s);
                fileName = Config.getProps("jmail.dir") + "\\" + stunum + "\\" + assignname + "\\" + MimeUtility.decodeText(fileName);
                System.out.println("有附件:" + fileName);
                File f = new File(fileName);
                // find a file that does not yet exist
                for (int i = 1; f.exists(); i++) {
                    String newName = fileName + " " + i;
                    f = new File(newName);
                }
                tm.put(f.getName(), f.getAbsolutePath());
                OutputStream out = new BufferedOutputStream(new FileOutputStream(f));
                // We can't just use p.writeTo() here because it doesn't
                // decode the attachment. Instead we copy the input stream 
                // onto the output stream which does automatically decode
                // Base-64, quoted printable, and a variety of other formats.
                InputStream in = new BufferedInputStream(p.getInputStream());
                int b;
                while ((b = in.read()) != -1) {
                    out.write(b);
                }
                out.flush();
                out.close();
                in.close();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    //base64解码  

    private String base64Decoder(String s) throws Exception {
        sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
        byte[] b = decoder.decodeBuffer(s);
        return (new String(b));
    }

    @Override
    public void run() {
        String url = protocol + "://" + username + "@" + pop3server + ":" + port + "/" + foldername;
        URLName server = new URLName(url);

        try {
            MailSession msession = new MailSession(pop3server, protocol, username, password);
            Session session = msession.getSession();

            // Connect to the server and open the folder
            Folder folder = session.getFolder(server);
            if (folder == null) {
                System.out.println("Folder " + server.getFile() + " not found.");
                System.exit(1);
            }
            folder.open(Folder.READ_ONLY);

            // Get the messages from the server
            //搜索指定条件的邮件,还有许多其它的搜索条件，请查阅相关的API
            SubjectRegexTerm[] t = new SubjectRegexTerm[1];
            String regEx = "^([0-9]+)\\s*([\\\u4e00-\\\u9fa5]+)\\s+([\\\u4e00-\\\u9fa5]+)$";
            t[0] = new SubjectRegexTerm(regEx);
            SearchTerm search = new OrTerm(t);
            Message[] messages = folder.search(search);
            int i = 0;
            //System.out.println("Thread receiver 启动");
            while (i < messages.length && this.timeToQuit != true) {
                System.out.println("------------ Message " + (i + 1)
                        + " ------------");

                // Print message headers
                Enumeration headers = messages[i].getAllHeaders();
                //if(messages[i].getFlags().contains(Flags.Flag.SEEN)){
                /** remove all header output
                while (headers.hasMoreElements()) {
                    Header h = (Header) headers.nextElement();
                    System.out.println(h.getName() + ": " + h.getValue());
                }
                **/
                String subject = messages[i].getSubject().trim();
                Pattern p = Pattern.compile(regEx);
                Matcher m = p.matcher(subject);
                boolean rs = m.find();
                // Enumerate parts
                stunum = m.group(1) + m.group(2);
                assignname = m.group(3);
                tm = new TreeMap();
                Object body = messages[i].getContent();
                if (body instanceof Multipart) {
                    processMultipart((Multipart) body);
                } else { // ordinary message
                    processPart(messages[i]);
                }
                if (rs) {
                    map.put("number", m.group(1));
                    map.put("stuName", m.group(2));
                    map.put("assginnum", m.group(3));
                    map.put("score", Config.getProps("perscore"));
                    String form = messages[i].getFrom()[0].toString();
                    form = MimeUtility.decodeText(form);
                    map.put("mailsender", form);
                    map.put("false", "未回复");
                }
                //}
                this.mc.update(messages.length, i + 1, map);
                i++;
                Students students = new Students();
                students.addStudent(m.group(2), m.group(1), "0", "0", "\\" + stunum + "\\" + m.group(1) + ".xml");
                String srcdetail = Config.getProps("jmail.dir") + "\\" + stunum + "\\" + m.group(1) + ".xml";
                //check the student xml file is exist
                Endir ed = new Endir(srcdetail);
                ed.createFile(m.group(2), m.group(1));
                //check over
                XmlData detailxml = new XmlData(srcdetail);
                detailxml.insertXml(m.group(3), Integer.parseInt(Config.getProps("perscore")),tm);
                Thread.sleep(1000);
//                if(i ==3)
//                    timeToQuit = true;
            }
            this.mc.setStopSend();
            // Close the connection 
            // but don't remove the messages from the server
            folder.close(false);

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            this.mc.setStopSend();
            System.out.println("接收完成");
        }
    }

    public void stopRunning() {
        System.err.println("Receiver stoped!");
        this.timeToQuit = true;
        System.err.println("Receiver stoped:" + this.timeToQuit);
    }
}